package ran.interceptor;

import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import ran.constants.Constants;
import ran.constants.HttpConstants;
import ran.service.TokenService;
import ran.utils.ThreadLocalUtil;


/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ran
 * Date: 2025-10-11
 * Time: 22:32
 */
@Component
@RefreshScope
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}") // 哪一个微服务实例化了这个bean, 这个secret就从哪个服务的配置中心中(nacos)获取
    private String secret; // 从nacos获取自定义的盐值




    // 请求处理之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 先给请求拦截下来, 进行token判断延长
        String token = getToken(request);
        if (StrUtil.isEmpty(token)) {
            return true;
        }
        // 延长token
        Claims claims = tokenService.getClaims(token, secret);
        tokenService.extendExpire(claims);
        Long userId = tokenService.getUserId(claims);
        String userKey = tokenService.getUserKey(claims);
        // 将userId 和 userKey存到 本地线程变量 ThreadLocalUtil 中, 不用再多次解析token来获取这两个值
        ThreadLocalUtil.set(Constants.USER_ID,userId);
        ThreadLocalUtil.set(Constants.USER_KEY,userKey);
        return true;
    }


    // 请求处理之后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 删除本地线程变量存储的数据
        ThreadLocalUtil.remove();
    }


    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(HttpConstants.AUTHENTICATION);
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX,"");
        }
        return token;
    }

}
